home *** CD-ROM | disk | FTP | other *** search
- /* kermit.c support routines and main entry point for Uemail file transfer
- * functions. Kermit send, receive, get, put, finish, and bye supported.
- * Buffer logging and direct ASCII transfer also available. All actions are
- * ASCII 7 bit files. Transfers are made into and out of Uemail buffers.
- */
-
- #include <stdio.h>
- #include <osbind.h>
- #include <ctype.h>
- #include "ed.h"
- #include "kermit.h"
-
-
- int emacsfile; /* if TRUE then \r become \n on ASCII transfers */
- char getfiln[NFILEN]; /* name for remote file get or put */
- char deflow[] = "XON/XOFF";
- static unsigned char *tsr_ptr = (char *)0x00fffa2d; /* See St internals */
- static long *hz_200 = (long *)0x000004ba;
- int *aaddress(); /* thanks Jwahar R. Bammi for this line A code */
- int *aline_addr; /* Ptr to base of Aline variables */
- int sav_row, sav_col;
- int flow = DEFLO; /* default flow control */
- int defbaud = 7;
- int bps = DEFBPS;
- unsigned long *hpterm; /* HOST */
-
- /* KERMIT CTRL command prompt for action and switch to appropriate state.
- * Returns TRUE on success. !TRUE on failures. Bound to ^_ and HELP on ST.
- */
- kermit(flg, _n)
- register int flg, _n;
- {
- static char command[9]; /* command */
- register char key;
- register int owf;
-
- owf = curwp->w_flag; /* save for redraw */
-
- if ((_n=mlreply("Kermit-ST> ",command,8)) != TRUE)
- return(_n==FALSE ? FALSE : ABORT);
-
- /* Initialize these values */
- /* Hope the first packet will get across OK */
-
- eol = CR; /* EOL for outgoing packets */
- quotech = '#'; /* Standard control-quote char "#" */
- pad = 0; /* No padding */
- padchar = '\0'; /* Use null if any padding wanted */
- timint = DEFTIME; /* Default timeout */
- parity = DEFPAR; /* Default to no parity */
- logfile = 0; /* Capture flag */
- emacsfile = 0; /* Trans to emacs (no EOF) */
- en8quote(FALSE);
-
- key = tolower(command[0]);
- switch (key)
- {
- case 'b': /* B = Bye */
- if(mlyesno("Logout remote")==TRUE)
- if(gencmdsw('L')==FALSE)
- {
- mlwrite("Remote does not ACK BYE");
- (*term.t_beep)();
- return(FALSE);
- }
- return(TRUE); /* No update */
- case 'c': /* C = Connect command */
- connect();
- break;
- case 'e': /* E = transmit to GNU_EMACS command */
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- gotobob(NULL, 1);
- update();
- mlwrite("[Transmitting %s to remote EMACS]",curbp->b_bna
- me);
- emacsfile = 1;
- trans();
- emacsfile = 0;
- connect();
- break;
- case 'f': /* F = Finish */
- if(gencmdsw('F')==FALSE)
- {
- mlwrite("Remote does not ACK FINISH");
- (*term.t_beep)();
- return(FALSE);
- }
- return(TRUE); /* No update */
- case 'g': /* G = Get command */
- if((_n=mlreply("Remote filename: ",getfiln,NFILEN))!=TRU
- E)
- return(_n);
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- gotoeob(NULL, 1);
- update();
- if((_n=getsw()) == FALSE)
- {
- (*term.t_beep)();
- mlreply("Get failed. Type <CR>",command,2);
- }
- break;
- case 'l': /* L = Log session */
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- gotoeob(NULL, 1);
- logfile = TRUE;
- connect();
- break;
- case 'r': /* R = Receive command */
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- gotoeob(NULL, 1);
- update();
- if((_n=recsw()) == FALSE)
- {
- (*term.t_beep)();
- mlreply("Receive failed. Type <CR>",command,2);
- }
- break;
- case 'p': /* P = Put command */
- if((_n=mlreply("Remote filename: ",getfiln,NFILEN))!=TRU
- E)
- return(_n);
- case 's': /* S = Send command */
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- if (key == 's')
- strcpy(getfiln,curbp->b_bname);
- gotobob(NULL, 1);
- update();
- if((_n=sendsw()) == FALSE)
- {
- if (key == 's')
- mlwrite("Send failed");
- else
- mlwrite("Put failed");
- (*term.t_beep)();
- }
- if (key == 's')
- connect();
- break;
- case 't': /* T = transmit command */
- if(usebuffer(NULL,NULL) != TRUE)
- return(FALSE);
- gotobob(NULL, 1);
- update();
- mlwrite("[Transmitting: %s]",curbp->b_bname);
- trans();
- connect();
- break;
- default:
- mlwrite("Connect, Send, Receive, Get, Put, Finish, Bye\
- , Log, Transfer");
-
- return(FALSE);
- }
- /* Restore controlling tty's modes */
-
- owf |= WFHARD; owf |= WFMODE;
- curwp->w_flag |= owf;
- sgarbf = TRUE; /* we know screen is garbage after connect */
- update();
- return(TRUE);
- }
-
- /*
- * c o n n e c t
- *
- * Establish a virtual terminal connection with the remote host, over an
- * assigned tty line.
- */
-
- connect()
- {
- register int c;
-
- setterm(REMOTE);
- while (1)
- {
- if (Bconstat(2))
- if(readcon() == FALSE)
- break;
- if (Bconstat(1))
- {
- c=readaux();
- ttputc(c);
- if (logfile)
- {
- if (c=='\n')
- {
- lnewline();
- continue;
- }
- if (c=='\r')
- continue;
- linsert(1,c);
- }
- }
- }
- setterm(HOST);
- return(FALSE);
- }
-
- /* set up terminal's screen and allow it to be saved for later.
- */
- setterm(f)
- int f;
- {
- static char scrbase[0x7d10];
- static unsigned char firsttime = TRUE;
- extern int deskcol;
-
- if (hpterm == NULL)
- hpterm = Physbase(); /* init TERM screen address */
- if (f == REMOTE)
- {
- Bconout(2,0x1b); /* disable cursor */
- Bconout(2,'f');
- copy(scrbase,hpterm,0x7d00);
- if (firsttime)
- {
- aline_addr = aaddress();
- Bconout(2,0x1b); /* clear screen */
- Bconout(2,'E');
- showhelp();
- sav_row = aline_addr[-13];/* save cursor position */
- sav_col = aline_addr[-14];
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[%s active at %dbps]",deflow,bps);
- firsttime = FALSE;
- }
- (*term.t_move)(sav_row,sav_col);
- Bconout(2,0x1b); /* enable cursor */
- Bconout(2,'e');
- return(TRUE);
- }
- else if (f == HOST)
- {
- sav_row = aline_addr[-13]; /* save cursor position */
- sav_col = aline_addr[-14];
- Bconout(2,0x1b); /* disable cursor */
- Bconout(2,'f');
- copy(hpterm,scrbase,0x7d00);
- ttopen(); /* restore uemail screen */
- Bconout(2,0x1b); /* enable cursor */
- Bconout(2,'e');
- return(TRUE);
- }
- else if (f == SHOWHELP)
- {
- sav_row = aline_addr[-13]; /* save cursor position */
- sav_col = aline_addr[-14];
- Bconout(2,0x1b); /* disable cursor */
- Bconout(2,'f');
- copy(hpterm,scrbase,0x7d00); /* save current screen */
- showhelp(); /* write help message */
- while(ttgetc()) /* wait for */
- if (scancode == 0x62) /* HELP key */
- break;
- copy(scrbase,hpterm,0x7d00); /* restore old screen */
- (*term.t_move)(sav_row,sav_col);
- Bconout(2,0x1b); /* enable cursor */
- Bconout(2,'e');
- return(TRUE);
- }
- }
-
- /*
- * return the base address of the line A variables
- * Bammi @ Case
- */
- int *
- aaddress()
- {
- asm("dc.w $A000");/* Line A trap - 0000 is init line-A */
- /* d0 and a0 now contain the address
- * so we can just return and the result
- * will be valid
- */
- }
-
- /* a mini-mlwrite for the terminal mode */
- /* VARARGS */
- mtwrite(fmt,arg1,arg2,arg3,arg4)
- register char *fmt;
- register long arg1,arg2,arg3,arg4;
- {
- static char buf[128];
-
- sprintf(buf,fmt,arg1,arg2,arg3,arg4);
- ttputc(0x1b);ttputc('j'); /* save cursor */
- (*term.t_move)(term.t_nrow,0);
- ttputc(0x1b);ttputc('l'); /* delete line */
- Cconws(buf);
- ttputc(0x1b);ttputc('k'); /* restore cursor */
- return(TRUE);
- }
-
- /* A modicum of help for the RS232 connection module */
- int
- showhelp()
- {
- register int i;
- i = 5;
-
- Crawio(0x1b);
- Crawio('p'); /* rev video on */
- (*term.t_move)(i++,17);
- Cconws(" ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-UNDO return to Uemail ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-B set the baud rate ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-C change color ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-E load an alias file ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-L load a macro file ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-O turn off flow control ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-R turn on RTS/CTS ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-X turn on XON/XOFF ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-T show the current time ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-CTRL-B send a break ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-CTRL-C run a program ");
- (*term.t_move)(i++,17);
- Cconws(" ALT-? this help message ");
- (*term.t_move)(i++,17);
- Cconws(" HELP this help message ");
- (*term.t_move)(i++,17);
- Cconws(" \r\n");
- Crawio(0x1b);
- Crawio('q'); /* rev video off */
- return(TRUE);
- }
-
- /* setbaud for RS232 (default is 1200) */
-
- int
- setbaud()
- {
- register int c;
-
- mtwrite("Baud rate [a/b/c/d/e] a = 300, \
- b = 1200, c = 2400, d = 9600, e = 19,200");
- c = ttgetc();
- switch(c)
- {
- case 'a':
- case 'A':
- defbaud = 9;
- bps = 300;
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- case 'b':
- case 'B':
- defbaud = 7;
- bps = 1200;
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- case 'c':
- case 'C':
- defbaud = 4;
- bps = 2400;
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- case 'd':
- case 'D':
- defbaud = 1;
- bps = 9600;
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- case 'e':
- case 'E':
- defbaud = 0;
- bps = 19200;
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- default:
- Rsconf(defbaud,flow,-1,-1,-1,-1);
- mtwrite("[Baud = %dbps]",bps);
- return(TRUE);
- }
- }
-
- /*
- * KERMIT utilities.
- */
-
- /* generic command for BYE and FINish */
- gencmdsw(cmd)
- char cmd;
- {
- int num, len; /* Packet number, length */
- packet[0] = cmd; /* Generic command */
- spack('G', 0, 1, packet); /* Send Generic command */
-
- switch(rpack(&len,&num,packet)) /* Get packet */
- {
- case 'Y':
- return(TRUE);
- case 'E':
- prerrpkt(packet);
- return(FALSE);
- default:
- return(FALSE);
- }
-
- }
-
- /*
- * b u f i l l
- *
- * Get a bufferful of data from the buffer that's being sent.
- * Only control-quoting and 8-bit quoting is done;
- * repeat count prefixes are not handled.
- */
-
- bufill(buffer)
- char buffer[]; /* Buffer */
- {
- register char t; /* Char read from file */
- register char *buffend; /* End of buffer pointer */
- register char *buffp; /* Pointer into buffer */
- register int unprintable; /* Is a character printable ?*/
- short eolflag = FALSE; /* kludge for VAX */
-
- buffend = &buffer[spsiz-9]; /* set up end of buffer pointer */
- buffp=buffer; /* and the current position */
-
- while(curwp->w_dotp != curbp->b_linep)
- {
- t = lgetc(curwp->w_dotp, curwp->w_doto);
- if (curwp->w_doto == llength(curwp->w_dotp))
- {
- t = eol;
- eolflag = TRUE; /* kludge for VAX */
- }
-
- unprintable = ((t<SP)||(t==DEL));
-
- /* Does this char require special handling? */
- if ((unprintable) || t==quotech)
- {
- *buffp++ = quotech; /* Quote the character */
- if (unprintable)
- t = ctl(t); /* and uncontrolify */
- }
- *buffp++ = t;
- if (eolflag)
- {
- eolflag = FALSE; /* be sure it gets \r\n pair */
- *buffp++ = quotech; /* this is for VAX/VMS */
- *buffp++ = ctl(LF);
- }
- forwchar(FALSE,1);
- /* Check length */
- if (buffp>=buffend) /* this is how you avoid pointer */
- return((int)buffp-(int)buffer); /* subtraction */
- } /* not (int)(buffp-buffer) */
- if (buffp == buffer)
- return(EOF);
- return((int)buffp-(int)buffer); /* Handle partial buffer */
- }
-
- /*
- * b u f e m p
- *
- * Put data from an incoming packet into the default buffer.
- */
-
- bufemp(buffer,len)
- char buffer[]; /* Buffer */
- int len; /* Length */
- {
- register int i; /* Counter */
- register char t; /* Character holder */
- register int highbit; /* place to hold quoted highbit */
-
- highbit = 0;
- for (i=0; i<len; i++) /* Loop thru the data field */
- {
- t = buffer[i]; /* Get a character */
- if (t == MYQUOTE) /* Control quote? */
- { /* Yes */
- t = buffer[++i]; /* Get the quoted character */
- /* Low order bits match quote char? */
- if (((t & 0177) != MYQUOTE) &&
- (!qflag || ((t & 0x7F)!=qbin)))
- t = ctl(t); /* No, uncontrollify it */
- }
- t |= highbit; /* set top bit if needed */
- highbit=0;
- if (t==eol)
- {
- lnewline();
- continue;
- }
- if (t=='\n')
- continue;
- linsert(1,t);
- }
- }
-
- int
- readaux()
- {
- int i;
-
- while(!Bconstat(1)) /* loop until line is ready or */
- if (i++ >= 32000) /* time is up */
- return(FALSE);
- return ((int)Bconin(1)); /* char not masked when read */
- }
-
- sauxstr(buf,len)
- char *buf;
- int len;
- {
- for(;len>0;len--)
- sendaux(*buf++);
- }
-
- sendaux(c)
- int c;
- {
- while(!Bcostat(1))
- {
- if (Bconstat(2))
- if (ttgetc()==0x07)
- return(FALSE);
- }
- Bconout(1,c); /* Send character */
- }
-
- /*
- * p r e r r p k t
- *
- * Print contents of error packet received from remote host.
- */
- prerrpkt(msg)
- char *msg;
- {
- mlwrite("ABORT: %s",msg);
- return;
- }
-
- en8quote(t)
- int t;
- {
- qflag = t;
- /* no binary files allowed */
- }
-
- /* tsr_ptr points to the 8 bit TSR register of the 68901
- * From Jwahar R. Bammi
- * send a break
- * Modifies Bit 3 in the TSR (reg 23) of the Mfp
- */
-
- sendbrk()
- {
- register long save_ssp;
- register long time;
-
- save_ssp = Super(0L); /* Super Mode */
-
- /* set bit 3 of the TSR */
- *tsr_ptr |= (unsigned char)8;
-
- /* wait for 250 ms -- you can adjust the duration
- * 250 ms seems to be almost a universal figure for break
- * duration.
- */
- time = *hz_200 + 50;
- while(*hz_200 < time)
- /* wait */ ;
- /* reset bit 3 of the tsr */
- *tsr_ptr &= (unsigned char)~8;
-
- Super(save_ssp); /* Back to user Mode */
- }
-
- /*
- * f l u s h i n p u t
- *
- * Dump all pending input to clear stacked up NACK's.
- */
- flushinput()
- {
- /* TOS Clear AUX receive buffer */
- while (Cauxis())
- Cauxin();
- }
-